<template>
  <div class="result-page-header">
    <!-- 背景图片 -->
    <img src="@/assets/material.jpg" class="result-back" />
    <!-- 搜索框 -->
    <n-h1>检&nbsp;索&nbsp;结&nbsp;果</n-h1>
    <div class="search-warp">
      <n-input-group>
        <n-input placeholder v-model:value="search_key" @keydown.enter.native="search"></n-input>
        <n-button color="#333333" @click="search">搜索</n-button>
      </n-input-group>
      <n-button
        color="#333333"
        v-if="!search_type"
        @click="searchInResult"
        class="search-in-result"
      >结果中检索</n-button>
    </div>
  </div>
  <!-- 下部分搜索结果 -->
  <div class="sub-warp">
    <div class="sub-left">
      <div class="grey-container">
        <div class="grey-container-title">
          <div></div>
          <span>筛选词条</span>
        </div>
        <div class="filter-container">
          <n-empty description="暂无筛选词条" v-if="filter_list.length === 0"></n-empty>
          <n-tag
            type="warning"
            v-for="(item, index) in filter_list"
            :key="index"
            closable
            @close="removeFilter(index)"
          ><n-ellipsis style="max-width: 100px;">{{ item.label }}</n-ellipsis></n-tag>
        </div>
        <div class="grey-container-bottom">
          <div class="filter-clear-btn" @click="clearFilter">重&nbsp;置</div>
          <div class="black-dash"></div>
        </div>
      </div>
      <div class="grey-container" v-if="!search_type">
        <div class="grey-container-title">
          <div></div>
          <span>分类</span>
        </div>
        <n-collapse>
          <n-collapse-item title="作者">
            <FilterItem :filter_list="author_filter_list" @chooseFilter="addAuthorFilter"></FilterItem>
          </n-collapse-item>
          <n-collapse-item title="语言">
            <FilterItem :filter_list="language_filter_list" @chooseFilter="addLanguageFilter"></FilterItem>
          </n-collapse-item>
          <n-collapse-item title="期刊/会议">
            <FilterItem :filter_list="venue_filter_list" @chooseFilter="addVenueFilter"></FilterItem>
          </n-collapse-item>
          <n-collapse-item title="年份">
            <FilterItem :filter_list="year_filter_list" @chooseFilter="addYearFilter"></FilterItem>
          </n-collapse-item>
        </n-collapse>
        <div class="grey-container-bottom">
          <div class="black-dash"></div>
        </div>
      </div>
      <ResultAnalyze v-if="!search_type" :charts_info="result_analyze" :is_loading="is_loading"/>
    </div>
    <div class="sub-right">
      <!-- 搜索结果 -->
      <div class="result-count">
        <div></div>
        <n-text italic>{{ countFormat(result_count) }}</n-text>
        <n-text>&nbsp;检索结果</n-text>
      </div>
      <div class="rank-type">
        <!-- 排序方式 -->
        <n-dropdown placement="bottom" trigger="click" :options="rank_type">
          <n-button text icon-placement="right" v-if="!search_type">
            <template #icon>
              <n-icon>
                <down-icon />
              </n-icon>
            </template>
            {{ select_rank_type.label }}
          </n-button>
        </n-dropdown>
        <!-- 文献学者切换 -->
        <n-switch @update:value="changeSearchType" v-model:value="search_type">
          <template #checked>学者</template>
          <template #unchecked>文献</template>
        </n-switch>
      </div>
      <div style="clear: both;"></div>
      <n-spin :show="is_loading">
        <AuthorList
          v-if="search_type"
          :page="page"
          :page_size="page_size"
          :authors="authors"
          :is_loading="is_loading"
          :result_count="result_count"
          @update-page="updagePage"
          @update-page-size="updagePageSize"
        />
        <PaperList
          v-else
          :page="page"
          :page_size="page_size"
          :papers="papers"
          :is_loading="is_loading"
          :result_count="result_count"
          @update-page="updagePage"
          @update-page-size="updagePageSize"
        />
      </n-spin>
    </div>
  </div>
</template>

<script setup lang='ts'>
import { ChevronDown as DownIcon } from '@vicons/ionicons5'
import { useMessage } from 'naive-ui';
import FilterItem from '@/views/search/components/FilterItem.vue'
import ResultAnalyze from '@/views/search/components/ResultAnalyze.vue';
import PaperList from '@/components/search/PaperList.vue'
import AuthorList from '@/components/search/AuthorList.vue'
import { getCurrentInstance, onMounted, Ref, ref, toRaw, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';

// 引入消息函数
const message = useMessage()

// api访问代理
const { proxy } = getCurrentInstance() as any

// 引入路由
const router = useRouter()
const route = useRoute()

const is_loading = ref(true)

// 检索关键词
const key_list: Ref<string[]> = ref([])

// 搜索结果数
const result_count = ref(0)

// 搜索类型 false 文献、true 学者
const search_type = ref(false)

// 检索关键词
const search_key = ref('')

// 初始页数和每页展示数
const page = ref(1)
const page_size = ref(10)

// 检索结果
let papers = ref([])

let authors = ref([])

// 分析数据
let result_analyze = ref({})

onMounted(() => {
  search_key.value = route.query.key as string
  init(search_key.value)
})

const init = ((key: string) => {
  let type = localStorage.getItem('search_type')
  if (type == null) {
    localStorage.setItem("search_type", 'paper');
  }

  search_type.value = type === 'author'

  key_list.value.length = 0
  key_list.value.push(key)

  if (search_type.value) {
    var params_author = {
      key: key_list.value[0],
      page: page.value,
      page_size: page_size.value
    }
    searchAuthor(params_author)
  } else {
    var params_paper = {
      key_list: JSON.stringify(key_list.value),
      rank_type: select_rank_type.value.key,
      page: page.value,
      page_size: page_size.value
    }
    searchPaper(params_paper)
  }
})

// 排序方式
const rank_type = [
  {
    label: '相关度',
    key: 0,
    props: {
      onClick: () => {
        select_rank_type.value = {
          label: '相关度',
          key: 0
        }
      }
    }
  },
  {
    label: '发布时间',
    key: 1,
    props: {
      onClick: () => {
        select_rank_type.value = {
          label: '发布时间',
          key: 1
        }
      }
    }
  },
  {
    label: '被引次数',
    key: 2,
    props: {
      onClick: () => {
        select_rank_type.value = {
          label: '被引次数',
          key: 2
        }
      }
    }
  },
  {
    label: '下载次数',
    key: 3,
    props: {
      onClick: () => {
        select_rank_type.value = {
          label: '下载次数',
          key: 3
        }
      }
    }
  },
]

// 选中的排序方式
const select_rank_type = ref({
  label: '相关度',
  key: 0
})

watch(select_rank_type, () => {
  searchFilter(1)
})

interface IFilter {
  id: number,
  label: string,
  count: number,
  type?: number
}

// 筛选标签列表 0作者 1语言 2期刊/会议 3年份
const filter_list: Ref<IFilter[]> = ref([])

let author_filter_list: Ref<IFilter[]> = ref([])

// 语言筛选列表
let language_filter_list: Ref<IFilter[]> = ref([])

// 期刊/会议筛选列表
let venue_filter_list: Ref<IFilter[]> = ref([])

// 年份筛选列表
let year_filter_list: Ref<IFilter[]> = ref([])

// 添加筛选 0作者，1机构，2期刊/会议，3年份，4语言
const addFilter = ((item: IFilter, type: number) => {
  for (let index = 0; index < filter_list.value.length; index++) {
    let element = filter_list.value[index];
    if (element.id === item.id && element.type === type) {
      message.warning("该筛选词条已添加")
      return
    }
  }
  item.type = type
  filter_list.value.push(toRaw(item))
  searchFilter(1);
})

// 添加作者筛选
const addAuthorFilter = ((index: number) => {
  addFilter(author_filter_list.value[index], 0)
})

// 添加语言筛选
const addLanguageFilter = ((index: number) => {
  addFilter(language_filter_list.value[index], 1)
})

// 添加期刊/会议筛选
const addVenueFilter = ((index: number) => {
  addFilter(venue_filter_list.value[index], 2)
})

// 添加年份筛选
const addYearFilter = ((index: number) => {
  addFilter(year_filter_list.value[index], 3)
})

// 清空筛选栏
const clearFilter = (() => {
  filter_list.value.length = 0
  searchFilter(1);
})

// 移除筛选项
const removeFilter = ((index: number) => {
  filter_list.value.splice(index, 1)
  searchFilter(1);
})

// 格式化数字显示方式
const countFormat = ((_num: number) => {
  var num = (_num || 0).toString()
  var result = '';
  while (num.length > 3) {
    result = ',' + num.slice(-3) + result;
    num = num.slice(0, num.length - 3);
  }
  if (num) { result = num + result; }
  return result;
})

// 更改搜索类型
const changeSearchType = ((value: boolean) => {
  filter_list.value.length = 0
  if (value) {
    localStorage.setItem("search_type", 'author');
  } else {
    localStorage.setItem("search_type", 'paper');
  }
  init(search_key.value)
})

// 检索
const search = (() => {
  if (search_key.value === '') {
    message.warning("请输入搜索关键词")
    return
  }
  router.replace({ path: '/search/result', query: { key: search_key.value } })
  init(search_key.value)
})

// 结果中检索
const searchInResult = (() => {
  if (search_key.value === '') {
    message.warning("请输入搜索关键词")
    return
  }

  page.value = 1

  key_list.value.push(search_key.value)

  var params = {
    key_list: JSON.stringify(key_list.value),
    rank_type: select_rank_type.value.key,
    page: page.value,
    page_size: page_size.value
  }

  searchPaper(params)
})

// 论文筛选
const searchFilter = ((value: number) => {
  page.value = value

  var params = {
    key_list: JSON.stringify(key_list.value),
    rank_type: select_rank_type.value.key,
    filter_list: JSON.stringify(filter_list.value),
    page: page.value,
    page_size: page_size.value
  }

  is_loading.value = true
  proxy.$api.search.filterPaper(params).then((result: any) => {
    if (result.success) {
      is_loading.value = false
      result_count.value = result.result_count
      papers.value = result.papers
      result_analyze.value = result.result_analyze
      calOther()
    } else {
      message.warning(result.msg)
    }
  }).catch(() => {
    message.error('未知错误')
  });
})

// 论文检索
const searchPaper = ((params: any) => {
  is_loading.value = true
  proxy.$api.search.searchPaper(params).then((result: any) => {
    if (result.success) {
      is_loading.value = false
      result_count.value = result.result_count
      papers.value = result.papers
      author_filter_list.value = result.author_filter_list
      language_filter_list.value = result.language_filter_list
      venue_filter_list.value = result.venue_filter_list
      year_filter_list.value = result.year_filter_list
      result_analyze.value = result.result_analyze
      calOther()
    } else {
      message.warning(result.msg)
    }
  }).catch(() => {
    message.error('未知错误')
  });
})

// 学者检索
const searchAuthor = ((params: any) => {
  is_loading.value = true
  proxy.$api.search.searchAuthor(params).then((result: any) => {
    if (result.success) {
      is_loading.value = false
      result_count.value = result.result_count
      authors.value = result.authors
    } else {
      message.warning(result.msg)
    }
  }).catch(() => {
    message.error('未知错误')
  });
})

// 更新页码
const updagePage = ((value: number) => {
  page.value = value
  searchFilter(page.value)
})

// 更新页条目数
const updagePageSize = ((value: number) => {
  page.value = 1
  page_size.value = value
  searchFilter(page.value)
})


// 计算分析图其他部分
const calOther = (() => {
  var in_chart = 0;
  (result_analyze.value as any).author_analyze.data.forEach((element: any) => {
    in_chart += element.value
  });
  (result_analyze.value as any).author_analyze.data.push({
    value: result_count.value - in_chart, name: "Other", id: ""
  });

  in_chart = 0;
  (result_analyze.value as any).venue_analyze.data.forEach((element: any) => {
    in_chart += element.value
  });
  (result_analyze.value as any).venue_analyze.data.push({
    value: result_count.value - in_chart, name: "Other", id: ""
  });
})
</script>

<style scoped>
.result-page-header {
  width: 100%;
}

.result-back {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 250px;
  -o-object-fit: cover;
  object-fit: cover;
  filter: grayscale(40%);
  -webkit-filter: grayscale(40%);
}

.search-warp {
  color: white;
  position: absolute;
  height: 200px;
  width: 700px;
  right: 200px;
  top: 120px;
}

.search-warp a {
  color: white;
  text-decoration: none;
  float: right;
  margin-top: 10px;
  margin-right: 10px;
}

.result-page-header :deep(.n-h1) {
  color: white;
  position: absolute;
  top: 72px;
  left: 150px;
  font-size: 4em;
  font-weight: bolder;
}

.search-warp :deep(.n-input) {
  height: 50px;
  font-size: 16px;
  line-height: 50px;
  border-radius: 4px;
  opacity: 90%;
}

.search-warp :deep(.n-button) {
  height: 50px;
  font-size: large;
  border-radius: 4px;
  opacity: 90%;
}

.search-in-result {
  height: 50px;
  font-size: large;
  border-radius: 4px;
  opacity: 90%;
  position: absolute;
  right: -120px;
}

.sub-warp {
  margin: 280px 8% 50px 8%;
}

.sub-left {
  float: left;
  width: 23%;
  margin-right: 2%;
}

.sub-right {
  float: left;
  width: 75%;
}

.result-count {
  display: flex;
}

.result-count :deep(div) {
  background: #ebc34a;
  height: 20px;
  width: 8px;
  margin-right: 5px;
}

.rank-type {
  float: right;
}

.rank-type :deep(.n-switch) {
  margin-left: 20px;
  --rail-color: #333333 !important;
  --rail-color-active: #40acbb !important;
}

.filter-container {
  background-color: #fafafa;
  padding: 10px;
}

.filter-container :deep(.n-tag) {
  margin: 3px;
}

.grey-container {
  background: #f0f0f0;
  padding-top: 4em;
  margin-bottom: 30px;
}

.grey-container :deep(.n-collapse) {
  background: #fafafa;
  padding: 10px 0 10px 0;
  --divider-color: #dcdcdc !important;
}

.grey-container :deep(.n-collapse-item) {
  padding-left: 10px;
}

.grey-container-title {
  display: flex;
  position: absolute;
  margin-top: -3em;
  font-weight: bold;
}

.grey-container-title :deep(div) {
  background: #000;
  height: 20px;
  width: 10px;
  margin-right: 5px;
}

.grey-container-title :deep(span) {
  font-size: large;
  margin-top: -3px;
}

.grey-container-bottom {
  background: #fafafa;
  position: relative;
  min-height: 20px;
  border-top: solid #dcdcdc 1px;
}

.filter-clear-btn {
  padding: 10px 20px;
  text-align: right;
  font-size: 1.3em;
  color: #3f3f3f;
  cursor: pointer;
}

.black-dash {
  width: 18px;
  height: 5px;
  background: #000;
  position: absolute;
  bottom: 0;
  right: 16px;
}

.spin {
  margin: auto;
}
</style>